package org.hkfree.ospf.tools;

import java.awt.Color;
import java.awt.geom.Point2D;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Map;

import org.hkfree.ospf.gui.mappanel.MapGraphComponent;
import org.hkfree.ospf.model.map.MapModel;
import org.hkfree.ospf.model.map.impl.LinkEdge;
import org.hkfree.ospf.model.map.impl.RouterVertex;
import org.hkfree.ospf.model.ospf.Link;
import org.hkfree.ospf.model.ospf.OspfModel;
import org.hkfree.ospf.model.ospf.Router;

/**
 * Exporter pro export modelu do souboru
 * @author Jan Schovánek
 */
public class Exporter {

    /**
     * Exportuje model do XGMML souboru vhodneho pro import do programu Cytoscape
     * @param file cilovy soubor
     * @param model model k exportu
     * @throws IOException
     */
    public static void exportModelToXGMML(File file, OspfModel model) throws IOException {
	Writer out = new BufferedWriter(new FileWriter(file));
	out.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
	out.write("<!-- \n    Generated by OspfVisualiser.\n\n    visit web: http://code.google.com/p/ospf-visualiser/ \n-->\n");
	out.write("<graph label=\""
		+ model.getModelName()
		+ "\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:cy=\"http://www.cytoscape.org\" xmlns=\"http://www.cs.rpi.edu/XGMML\"  directed=\"1\">");
	out.write("\n");
	for (Router r : model.getRouters()) {
	    out.write("<node label=");
	    out.write("\"" + r.getId() + "\"");
	    out.write(" id=");
	    out.write("\"" + r.getId() + "\">");
	    out.write("<att name=\"NODE_TYPE\" value=\"DefaultNode\"/>");
	    out.write("<att name=\"ip\" value=\"" + r.getId() + "\"/>");
	    out.write("<att name=\"canonicalName\" value=\"" + r.getName() + "\"/>");
	    out.write("<graphics type=\"ELLIPSE\" h=\"40.0\" w=\"40.0\"/>");
	    out.write("</node>");
	    out.write("\n");
	}
	for (Link ol : model.getLinks()) {
	    out.write("<edge label=");
	    out.write("\"" + ol.getLinkIDv4() + "\"");
	    out.write(" source=");
	    out.write("\"" + ol.getOspfLinkData().get(0).getRouter().getId() + "\"");
	    out.write(" target=");
	    out.write("\"" + ol.getOspfLinkData().get(1).getRouter().getId() + "\"");
	    out.write("></edge>");
	    out.write("\n");
	}
	out.write("</graph>");
	out.close();
    }


    /**
     * Export modelu do SVG formatu
     * @param file
     * @param model
     * @param graph
     * @throws IOException
     */
    public static void exportModelToSVG(File file, MapModel model, MapGraphComponent graph) throws IOException {
	Writer out = new BufferedWriter(new FileWriter(file));
	out.write("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n");
	out.write("<!-- \n    Generated by OspfVisualiser.\n\n    visit web: http://code.google.com/p/ospf-visualiser/ \n-->\n\n");
	//css styly
	out.write("<defs>\n<style type=\"text/css\"><![CDATA[\n");
	out.write(".linkLabel   { fill: black; font-size: 8; font-family: verdana, sans-serif;  }\n");
	out.write(".routerLabel { fill: black; font-size: 9; font-family: verdana, sans-serif;  }\n");
	out.write(".multiLink   { stroke-width: 1; stroke: black; fill: white }\n");
	out.write(".link        { stroke-width: 1 }\n");
	out.write(".router      { stroke-width: 1 }\n");
	out.write("]]></style>\n</defs>\n\n");
	//obsah, svg komponenty
	Map<RouterVertex, Point2D> routers = graph.getRouterVertexPositions();
	List<LinkEdge> edges = model.getLinkEdges();
	for (LinkEdge le : edges) {
	    if (le.isIPv4()) {
        	    out.write("<line class=\"link\" " +
        	    	    "x1=\"" + routers.get(le.getVertex1()).getX() + "\" " +
        		    "y1=\"" + routers.get(le.getVertex1()).getY() + "\" " +
        		    "x2=\"" + routers.get(le.getVertex2()).getX() + "\" " +
        		    "y2=\"" + routers.get(le.getVertex2()).getY() + "\" " +
        		    "stroke=\"#" + Integer.toHexString(((Color) le.getLineColor()).getRGB()).substring(2) + "\" " +
        		    "/>\n");
        	    // linkEdge text
        	    out.write("<text class=\"linkLabel\" " +
        		    "x=\"" + (routers.get(le.getVertex1()).getX() + routers.get(le.getVertex2()).getX()) / 2 + "\" " +
        		    "y=\"" + +(routers.get(le.getVertex1()).getY() + routers.get(le.getVertex2()).getY()) / 2 + "\" " +
        		    ">" + le.getCost1v4() + "-" + le.getCost2v4() + "</text>\n");
	    }
	}
	for (RouterVertex rv : routers.keySet()) {
	    if (rv.getColorFill() == null)
		continue;
	    if (rv.isMultilink()) {
		// multilink
		out.write("<rect class=\"multiLink\" " +
			"width=\"10\" height=\"10\" " +
			"x=\"" + (routers.get(rv).getX() - 5) + "\" " +
			"y=\"" + (routers.get(rv).getY() - 5) + "\"/>\n");
	    } else {
		// router symbol
		out.write("<circle class=\"router\" " +
			"r=\"10\" " +
			"fill=\"#" + Integer.toHexString(rv.getColorFill().getRGB()).substring(2) + "\" " +
			"stroke=\"#" + Integer.toHexString(rv.getColorStroke().getRGB()).substring(2) + "\" " +
			"cx=\"" + routers.get(rv).getX() + "\" " +
			"cy=\"" + routers.get(rv).getY() + "\"/>\n");
		// router text
		out.write("<text class=\"routerLabel\" " +
			"x=\"" + (routers.get(rv).getX() + 12) + "\" " +
			"y=\"" + (routers.get(rv).getY() + 12) + "\" " +
			">" + rv.getName() + "</text>\n");
	    }
	}
	out.write("</svg>");
	out.close();
    }
}
